# ifndef __GdbFile_H_
# define __GdbFile_H_

//
// Garmin MapSource GDB file format structure.
// (c) Konstantin Galichsky (kg@geopainting.com), 2002-2005
// Garmin and MapSource are registered trademarks or trademarks of Garmin Ltd. or one of its subsidiaries.
//
// NOTE: the code is tested for MapSource 6.0-6.5 only.
//

# ifdef _MSC_VER
#	pragma pack (push, 1)
# endif

	//
	// Each GDB file begins with these 6 bytes.
	//

const BYTE g_pGdbSignature [6] = {'M', 's', 'R', 'c', 'f', '\0'};

	// The header for MapSource 6.0.
extern const BYTE g_pGdbHeader [];
extern const size_t c_cGdbHeaderSize;

extern const BYTE g_pGdbTail   [];
extern const size_t c_cGdbTailSize;

	//
	// Each record in GDB file begins with this header.
	//

struct CGdbRecordHdr {
	// Number of bytes in the record (except this header).
	DWORD dwLen;

	// Type of the record:
	// 'D' - file format version (always the first record), see CGdbFormatVersion
	// 'A' - MapSource version (always the second record), see CGdbMSVersion
	// 'V' - probably end marker (always the last record), two bytes 0x00, 0x01
	// 'W' - waypoint, see CGdbWaypointHdr, CGdbWaypoint2, CGdbWaypoint3
	// 'T' - track, see CGdbTrackHdr, CGdbTrack2, CGdbTrackPoint
	// 'R' - route
	// 'M' - map reference
	// 'V' - map collection (end of file)
	BYTE  btType;
};

	//
	// File format version.
	//

struct CGdbFormatVersion : public CGdbRecordHdr {
	// 0x6B - saved by MS 6.0-6.3 (GDB version 1)
	// 0x6C - saved by MS 6.5     (GDB version 2)
	// 0x6D - saved by MS 6.12    (GDB version 3)
	WORD wdVersion;
};

	//
	// MapSource version.
	//

struct CGdbMSVersion : public CGdbRecordHdr {
	// 0x0258 - MapSource 6.0
	WORD wVersion;

	// Three zero-terminated strings with MapSource builder's nickname
	// and date/time of build.
	// Example: "hales\0Nov 18 2002\014:11:40\0"
	char strBuildInfo [1];
};

	//
	// Waypoint.
	//

struct CGdbWaypointHdr : public CGdbRecordHdr {
	// The label.
	char strName [1];     // Null-terminated.
};

struct CGdbWaypoint2 {
	DWORD dwClass;        // 0x00 for user waypoint

	BYTE  strCountry [1]; // ??

	DWORD dwMapSegmentID; // 0x00000000 for user waypoint. Map Segment ID for map objects. 
	DWORD dwMapObjectID;  // 0xFFFFFFFF for user waypoint. Map Object ID for map objects -
	                      // unique identifier for each road, POI, river, area, intersection, city, airport etc.

	DWORD dwSubclass10;   // Waypoint subclass for auto-routes. User waypoint is 0xFFFFFFFF.
	DWORD dwSubclass11;   // Waypoint subclass for auto-routes. User waypoint is 0xFFFFFFFF.
	WORD  wWptSubclass;   // 0x0000 for user waypoint.
	DWORD dwSubclass3;    // Waypoint subclassing for auto-routes. User waypoint is 0xFFFFFFFF.

	// Lat/Lon, in arcs (180/2^31 deg).
	LONG  lY;
	LONG  lX;
};

	//
	// Route.
	//

struct CGdbRouteHdr : public CGdbRecordHdr {
	// The label.
	char strName [1];     // Null-terminated.
};

struct CGdbRouteLink2 {
	DWORD dwClass;        // 0x00 for user waypoint

	BYTE  strCountry [1]; // ??

	DWORD dwMapSegmentID; // 0x00000000 for user waypoint. Map Segment ID for map objects. 
	DWORD dwMapObjectID;  // 0xFFFFFFFF for user waypoint. Map Object ID for map objects -
	                      // unique identifier for each road, POI, river, area, intersection, city, airport etc.

	DWORD dwSubclass10;   // Waypoint subclass for auto-routes. User waypoint is 0xFFFFFFFF.
	DWORD dwSubclass11;   // Waypoint subclass for auto-routes. User waypoint is 0xFFFFFFFF.
	WORD  wWptSubclass;   // 0x0000 for user waypoint.
	DWORD dwSubclass3;    // Waypoint subclassing for auto-routes. User waypoint is 0xFFFFFFFF.
};

struct CGdbRouteLink3 {
	BYTE btFlag;          // Seems to be 0x00 the whole time
	DWORD dwUnknown3;     // ?? 0 or 3
	DWORD dwSubclass3;    // ?? 0x0 if dwUnknown3==3, else it is a copy of Subclass3
	DWORD dwMapSegmentID; // 0x0 if dwUnknown3==3, else it is a copy of the MapSegmentID
	WORD  wWptSubclass;   // 0x0 if dwUnknown3==3, else ?? it is copy of WptSubclass
	DWORD dw3;

	DWORD dwPoints;
};

	//
	// Track.
	//

struct CGdbTrackHdr : public CGdbRecordHdr {
	// The label.
	char strName [1];     // Null-terminated.
};

struct CGdbTrack2 {
	BYTE  btDisplayOnGPS; // 1 - display, 0 - hide
	DWORD dwColor;        // 0

	// The number of points in the track.
	DWORD dwPoints;
};

	//
	// Map reference.
	//

struct CGdbMapHdr : public CGdbRecordHdr {
	WORD  wProductID;
	WORD  wFamilyID;
    DWORD dwImgID;

    char strProductName [1];
//	char strMapName [1];
//	char strAreaName [1];
};

# ifdef _MSC_VER
#	pragma pack (pop)
# endif


# endif // __GdbFile_H_
